home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Online / QMail / docs / INTERNALS < prev    next >
Encoding:
Text File  |  1997-04-15  |  6.8 KB  |  156 lines

  1. 1. Overview
  2.  
  3. Here's the data flow in the qmail suite:
  4.  
  5.  qmail-smtpd --- qmail-queue --- qmail-send --- qmail-rspawn --- qmail-remote
  6.                /                     |      \
  7. qmail-inject _/                 qmail-clean  \_ qmail-lspawn --- qmail-local
  8.  
  9. Every message is added to a central queue directory by qmail-queue.
  10. qmail-queue is invoked as needed, usually by qmail-inject for locally
  11. generated messages, qmail-smtpd for messages received through SMTP,
  12. qmail-local for forwarded messages, or qmail-send for bounce messages.
  13.  
  14. Every message is then delivered by qmail-send, in cooperation with
  15. qmail-lspawn and qmail-rspawn, and cleaned up by qmail-clean. These four
  16. programs are long-running daemons.
  17.  
  18. The queue is designed to be crashproof, provided that the underlying
  19. filesystem is crashproof. All cleanups are handled by qmail-send and
  20. qmail-clean without human intervention. See section 6 for more details.
  21.  
  22.  
  23. 2. Queue structure
  24.  
  25. Each message in the queue is identified by a unique number, let's say
  26. 457. The queue is organized into several directories, each of which may
  27. contain files related to message 457:
  28.  
  29.    mess/457: the message
  30.    todo/457: the envelope: where the message came from, where it's going
  31.    intd/457: the envelope, under construction by qmail-queue
  32.    info/457: the envelope sender address, after preprocessing
  33.    local/457: local envelope recipient addresses, after preprocessing
  34.    remote/457: remote envelope recipient addresses, after preprocessing
  35.    bounce/457: permanent delivery errors
  36.  
  37. Here are all possible states for a message. + means a file exists; -
  38. means it does not exist; ? means it may or may not exist.
  39.  
  40.    S1. -mess -intd -todo -info -local -remote -bounce
  41.    S2. +mess -intd -todo -info -local -remote -bounce
  42.    S3. +mess +intd -todo -info -local -remote -bounce
  43.    S4. +mess ?intd +todo ?info ?local ?remote -bounce (queued)
  44.    S5. +mess -intd -todo +info ?local ?remote ?bounce (preprocessed)
  45.  
  46. Guarantee: If mess/457 exists, it has inode number 457.
  47.  
  48.  
  49. 3. How messages enter the queue
  50.  
  51. To add a message to the queue, qmail-queue first creates a file in a
  52. separate directory, pid/, with a unique name. The filesystem assigns
  53. that file a unique inode number. qmail-queue looks at that number, say
  54. 457. By the guarantee above, message 457 must be in state S1.
  55.  
  56. qmail-queue renames pid/whatever as mess/457, moving to S2. It writes
  57. the message to mess/457. It then creates intd/457, moving to S3, and
  58. writes the envelope information to intd/457.
  59.  
  60. Finally qmail-queue creates a new link, todo/457, for intd/457, moving
  61. to S4. At that instant the message has been successfully queued, and
  62. qmail-queue leaves it for further handling by qmail-send.
  63.  
  64. qmail-queue starts a 24-hour timer before touching any files, and
  65. commits suicide if the timer expires.
  66.  
  67.  
  68. 4. How queued messages are preprocessed
  69.  
  70. Once a message has been queued, qmail-send must decide which recipients
  71. are local and which recipients are remote. It may also rewrite some
  72. recipient addresses.
  73.  
  74. When qmail-send notices todo/457, it knows that message 457 is in S4. It
  75. removes info/457, local/457, and remote/457 if they exist. Then it reads
  76. through todo/457. It creates info/457, possibly local/457, and possibly
  77. remote/457. When it is done, it removes intd/457. The message is still
  78. in S4 at this point. Finally qmail-send removes todo/457, moving to S5.
  79. At that instant the message has been successfully preprocessed.
  80.  
  81.  
  82. 5. How preprocessed messages are delivered
  83.  
  84. Messages at S5 are handled as follows. Each address in local/457 and
  85. remote/457 is marked either NOT DONE or DONE.
  86.  
  87.    DONE: The message was successfully delivered, or the last delivery
  88.          attempt met with permanent failure. Either way, qmail-send
  89.      should not attempt further delivery to this address.
  90.  
  91.    NOT DONE: If there have been any delivery attempts, they have all
  92.              met with temporary failure. Either way, qmail-send should
  93.              try delivery in the future.
  94.  
  95. qmail-send may at its leisure try to deliver a message to a NOT DONE
  96. address. If the message is successfully delivered, qmail-send marks the
  97. address as DONE. If the delivery attempt meets with permanent failure,
  98. qmail-send first appends a note to bounce/457, creating bounce/457 if
  99. necessary; then it marks the address as DONE.
  100.  
  101. qmail-send may handle bounce/457 at any time, as follows: it (1) injects
  102. a new bounce message, created from bounce/457 and mess/457; (2) deletes
  103. bounce/457.
  104.  
  105. When all addresses in local/457 are DONE, qmail-send deletes local/457.
  106. Same for remote/457. 
  107.  
  108. When local/457 and remote/457 are gone, qmail-send eliminates the
  109. message, as follows. First, if bounce/457 exists, qmail-send handles it
  110. as described above. Once bounce/457 is definitely gone, qmail-send
  111. deletes info/457, moving to S2, and finally mess/457, moving to S1.
  112.  
  113.  
  114. 6. Cleanups
  115.  
  116. If the computer crashes while qmail-queue is trying to queue a message,
  117. or while qmail-send is eliminating a message, the message may be left in
  118. state S2 or S3.
  119.  
  120. When qmail-send sees a message in state S2 or S3---other than one
  121. it is currently eliminating!---where mess/457 is more than 36 hours old,
  122. it deletes intd/457 if that exists, then deletes mess/457. Note that any
  123. qmail-queue handling the message must be dead.
  124.  
  125. Similarly, when qmail-send sees a file in the pid/ directory that is
  126. more than 36 hours old, it deletes it.
  127.  
  128. Cleanups are not necessary if the computer crashes while qmail-send is
  129. delivering a message. At worst a message may be delivered twice. (There
  130. is no way for a distributed mail system to eliminate the possibility of
  131. duplication. What if an SMTP connection is broken just before the server
  132. acknowledges successful receipt of the message? The client must assume
  133. the worst and send the message again. Similarly, if the computer crashes
  134. just before qmail-send marks a message as DONE, the new qmail-send must
  135. assume the worst and send the message again. The usual solutions in the
  136. database literature---e.g., keeping log files---amount to saying that
  137. it's the recipient's computer's job to discard duplicate messages.)
  138.  
  139.  
  140. 7. Further notes
  141.  
  142. Currently info/457 serves two purposes: first, it records the envelope
  143. sender; second, its modification time is used to decide when a message
  144. has been in the queue too long. In the future info/457 may store more
  145. information. Any non-backwards-compatible changes will be identified by
  146. version numbers.
  147.  
  148. When qmail-queue has successfully placed a message into the queue, it
  149. pulls a trigger offered by qmail-send. Here is the current triggering
  150. mechanism: lock/trigger is a named pipe. Before scanning todo/,
  151. qmail-send opens lock/trigger O_NDELAY for reading. It then selects for
  152. readability on lock/trigger. qmail-queue pulls the trigger by writing a
  153. byte O_NDELAY to lock/trigger. This makes lock/trigger readable and
  154. wakes up qmail-send. Before scanning todo/ again, qmail-send closes and
  155. reopens lock/trigger.
  156.